import re

from .models import User, QQUser
from rest_framework.views import Response
from rest_framework import serializers
from django_redis import get_redis_connection
from utils import tjws
from oauth import constants


class QQUserSerializer(serializers.Serializer):
    mobile = serializers.CharField()
    password = serializers.CharField()
    sms_code = serializers.CharField()
    access_token = serializers.CharField()

    def validate(self, attrs):
        # 1.验证手机号码
        mobile = attrs.get('mobile')
        # 如果这里这样判断了，那么那些注册过的用户就不能登录了，因为直接就报异常了，根本就不会到下面的create了
        # 因为我下面要根据手机是否存在进行逻辑处理
        # if User.objects.filter(mobile=mobile).count() > 0:
        #     raise serializers.ValidationError('手机号码已经注册')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            raise serializers.ValidationError('手机号码格式不正确')

        # 2.验证短信验证码
        redis_cli = get_redis_connection('verify_codes')
        sms_code_request = attrs.get('sms_code')
        sms_code_redis = redis_cli.get('sms_code_' + mobile)
        # 验证码过期了就拿不到了
        if not sms_code_redis:
            raise serializers.ValidationError('短信验证码已过期')
        # 这里记得删除验证码
        redis_cli.delete('sms_code' + mobile)
        if int(sms_code_redis) != int(sms_code_request):
            raise serializers.ValidationError('短信验证码不正确')

        # 3.验证access_token
        access_token = attrs.get('access_token')
        # 解密  因为加密传的也是一个字典键值都为openid ==>{“openid”：openid}
        data_dict = tjws.loads(access_token, constants.SAVE_QQ_USER_TOKEN_EXPIRES)

        # 如果过期了就取不到这个access_token了
        if data_dict is None:
            raise serializers.ValidationError("access_token过期")

        # 4.先存到attrs里面，方便我们查询和创建QQ对象的时候使用，后续create会用到
        openid = data_dict.get('openid')
        attrs['openid'] = openid

        return attrs

    def create(self, validated_data):
        mobile = validated_data.get('mobile')
        password = validated_data.get('password')
        openid = validated_data.get('openid')
        # 判断手机号码有没有存在
        try:
            user = User.objects.get(mobile=mobile)
        except:
            # 这里是不存在的情况，先创建一个用户在到后面的时候再和一个QQ号码绑定，因为我们这里是使用了QQ授权登录
            # 等于用QQ来创建一个用户
            user = User()
            user.username = mobile
            user.mobile = mobile
            user.set_password(password)
            user.save()

        else:
            # 这里是存在的情况
            # 进行密码对比, 如果密码对比正确了就代表这个号码已经注册过用户了，然后把这个QQuser的user外键和那个跟用户绑在一起
            if not user.check_password(password):
                # 如果错了就表示这个手机号码不匹配当前用户输入的密码，就表示这个手机号码不是当前这个用户注册的
                raise serializers.ValidationError('手机已经被注册')

        # 不管怎样到最后都要把一个QQ号码和正常注册的用户绑定，就是在auth_qq里面添加用户和QQ用户的关系
        # 创建QQ用户并保存到数据库
        qquser = QQUser()
        qquser.user = user
        qquser.openid = openid
        qquser.save()
        return qquser
